﻿/// <reference path="jquery-2.0.3.js" />
/// <reference path="jquery.ba-resize.js" />
/// <reference path="jquery.mousewheel.js" />
/// <reference path="LiberUI.Base.js" />
/// <reference path="LiberUI.Controller.js" />
/// <reference path="LiberUI.Action.js" />

//#region 布局控件-表单
function Form(_srcElm, _opt) {
	/// <summary>
	/// 创建一个表单容器
	/// </summary>
	/// <param name="_srcElm"></param>
	/// <param name="_opt"></param>
	/// <returns type=""></returns>
    Controller.call(this, _srcElm, _opt);
    var instance = this;
    instance.Option = $.extend({}, this.Option, FormOption,_opt);
    instance.Controllers = [];
    instance.colWidth = parseInt(100 / instance.Option.ColumnPerRow);
    instance._member.actionBar = $("<div>").addClass(instance.Option.StyleForAction).appendTo(instance._member.$rootElm);
    instance._member.$rootElm.addClass(instance.Option.Style);
    instance.FocusedItem = -1;

    function onItemFocus(ev) {
        instance.IsFocused = true;
        instance.FocusedItem = parseInt(ev.target.attr("tab"));
    };

    function tabItem(ev) {
        var tab =parseInt($(ev.target).attr("tab"));
        tab++;
        if (tab < instance.Controllers.length) {
            $(ev.target).blur();
            instance.Controllers[tab].focus();
            return;
        }
    };
    instance._member.vf_onHide = function () {
        instance.IsFocused = false;
        instance.FocusedItem = -1;
    };

    instance._member.vf_disable = function () {
        for (var i in instance.Controllers) {
            if (i instanceof Controller) {
                i.disable();
            }
        }
    };
    instance._member.vf_enable = function () {
        for (var i in instance.Controllers) {
            if (i instanceof Controller) {
                i.enable();
            }
        }
    };
    instance._member.vf_onDispose = function (ev) {
        for (var i = 0, n = instance.Controllers.length; i < n; i++) {
            instance.Controllers[i].off("focus", onItemFocus);
            instance.Controllers[i].off("click", onItemFocus);
            KeybordHelper.off(instance.Controllers[i], "enter", tabItem);
            KeybordHelper.off(instance.Controllers[i], "tab", tabItem);
            instance.Controllers[i].dispose();
            instance.Controllers[i] = null;
        }
        instance.Controllers = [];
    };

    instance._member.vf_reset = function () {
        for (var i = 0, n = instance.Controllers.length; i < n; i++) {
            instance.Controllers[i].reset();
        }
    }

    this.AddItem = function (_title, _uiItem, _col,_required) {
    	/// <summary>
    	/// 向表单中添加一个元素
        /// </summary>
    	/// <param name="_title">标题</param>
    	/// <param name="_uiItem">元素项（JQuery DOM或Controller）</param>
    	/// <param name="_col">元素横跨的列数，max表示占据整个表单宽度，否则由Option.ColumnPerRow决定宽度</param>
        /// <returns type="">当前Form实例</returns>
        var ct = $("<div class='FormColumn'></div>");
        if (!_required) {
            ct.append($("<h4>").text(_title));
        }
        else {
            ct.append($("<h4>").addClass('required').text(_title));
        }

        var index=instance.Controllers.length;
        switch (_col) {
            case "max":
                ct.css("width", "100%");
                break;
            default:
                _col = parseInt(_col);
                if ($.isNumeric(_col)){
                    if (_col > instance.Option.ColumnPerRow) {
                        ct.css("width", "100%");
                    }
                    else {
                        ct.css("width", _col * instance.colWidth + '%');
                    }
                }
                else {
                    ct.css("width", instance.colWidth + '%');
                }
        }
        if (_uiItem instanceof Controller) {
            ct.append(_uiItem.attr('tab', index).dom());

        }
        else if (ObjHelper.IsElement(_uiItem)) {
            ct.append(_uiItem.attr("tab", index));
            if (_uiItem.is('input')) {
                KeybordHelper.on(_uiItem, "enter", tabItem);
                KeybordHelper.on(_uiItem, "tab", tabItem);
            }
        }
        
        instance.Controllers.push(_uiItem);
        _uiItem.on("focus", onItemFocus);
        _uiItem.on("click", onItemFocus);
        
        instance._member.$rootElm.append(ct);
        return this;
    };

    this.GetItem = function (_index) {
    	/// <summary>
    	/// 获取指定索引的子控件
    	/// </summary>
        /// <param name="_index">索引</param>
        if (!ObjHelper.IsEmpty(_index)) {
            _index = parseInt(_index);
            if (_index > -1 && _index < instance.Controllers.length) {
                return instance.Controllers[_index];
            }
        }
        return undefined;
    };

    Form.constructor = Form;
    return this;
}
Form.prototype = Controller.prototype;
var FormOption = {
    Style: "Form",  //基础样式类
    StyleForItemTitle: "", //用于每个子控件的标题的样式，默认h4元素，无其他样式
    StyleForAction: "FormActions", //用于表单可用操作按钮的容器样式
    StyleForHandler: "FormHandle", //用于表单控制菜单的容器样式
    ColumnPerRow: 3,  //每行容纳的子控件数量
    Propagation:true  //对于容器型控件，需要将DOM事件向上冒泡
};
//#endregion

//#region 布局容器-列表
function List(_srcElm, _opt) {
    Controller.call(this, _srcElm, _opt);
    var instance = this;
    instance.Option = $.extend({},this.Option,ListOption,_opt);

    var tmp = document.createDocumentFragment();
    var slctedItemIndex = -1; //当前选中的项索引
    var focusItemIndex = -1; //当前焦点（鼠标悬停或键盘操作）项索引
    var focusedRow = null; //当前焦点（鼠标悬停或键盘操作）项
    var data = [];  //数据集合
    var vItems = []; //可见行元素集合
    var nullTip = $("<li>").addClass(instance.Option.StyleForNull).text(instance.Option.TipForNull).appendTo(tmp);
    var fnGetKey = null;
    var fnPredicate = null;
    var jobFilter = null;
    var key = "";
    var cache = [];

    if (instance.Option.ShowHead == true) {
        instance._member.head = $('<div>').addClass(instance.Option.StyleForHead).appendTo(instance._member.$rootElm);
    }
    instance._member.body = $('<ul>').addClass(instance.Option.StyleForBody).appendTo(instance._member.$rootElm);
    if (instance.Option.ShowFoot == true) {
        instance._member.foot = $('<div>').addClass(instance.Option.StyleForFoot).appendTo(instance._member.$rootElm);
    }
    if (instance.Option.ShowNullTip == true) {
        instance._member.body.append(nullTip.show());
    }

    function append(_data, _pos) {
        nullTip.hide().appendTo(tmp);
        var sIndex = data.length;
        var eIndex = sIndex + _data.length;
        data = data.concat(_data);
        var refItem = vItems[_pos];

        var tmpItems = [];
        for (var i = sIndex; i < eIndex; i++) {
            var v = instance.af_makeView(data[i]);
            tmpItems.push(makeItem(i,data[i],v));
        }
        for (var i = 0; i < tmpItems.length; i++) {
            if (tmpItems[i].PItem) {
                //如果指定了父项，应插入到父项的下一个兄弟的前面
                var nxt = tmpItems[i].PItem.Row.nextUntil("[TreeLv=" + tmpItems[i].PItem.TreeLv + "]");
                if (nxt.length > 0) {
                    tmpItems[i].Row.insertBefore(nxt.first()).fadeIn();
                }
                else {
                    tmpItems[i].Row.insertAfter(tmpItems[i].PItem.Row).fadeIn();
                }
                
            }
            else if(refItem){
                tmpItems[i].Row.insertAfter(refItem.Row).fadeIn();
                refItem = tmpItems[i];
            }
            else {
                instance._member.body.append(tmpItems[i].Row.fadeIn());
            }
        }
    };
    function prepend(_data, _pos) {
        nullTip.hide().appendTo(tmp);
        var sIndex = data.length;
        var eIndex = sIndex + _data.length;
        data = data.concat(_data);
        var refItem = vItems[_pos];

        var tmpItems = [];
        for (var i = sIndex; i < eIndex; i++) {
            var v = instance.af_makeView(data[i]);
            tmpItems.push(makeItem(i, data[i], v));
        }
        for (var i = tmpItems.length-1; i >-1; i--) {
            if (tmpItems[i].PItem) {
                //如果指定了父项
                var nxt = tmpItems[i].PItem.Row.nextUntil("[TreeLv=" + tmpItems[i].TreeLv + "]");
                if (nxt.length > 0) {
                    //如果存在同级兄弟
                    tmpItems[i].Row.insertBefore(nxt.first()).fadeIn();
                }
                else {
                    tmpItems[i].Row.insertAfter(tmpItems[i].PItem.Row).fadeIn();
                }
            }
            else if (refItem) {
                tmpItems[i].Row.insertBefore(refItem.Row).fadeIn();
            }
            else {
                instance._member.body.prepend(tmpItems[i].Row.fadeIn());
            }
        }
    };
    function makeItem(_dataIndex, _data, _view) {
        var item = {};
        var pItem = null;
        item.Update = updateRow;
        item.DataIndex = _dataIndex;
        item.Data = _data;
        item.TreeLv = 0;
        item.RowIndex = vItems.length;
        item.Row = $("<li>").addClass(instance.Option.StyleForRow);
        item.Row.on('click', onRowClick).on('dblclick',onRowDBClick);
        item.Row.appendTo(tmp);
        //item.Head = $("<span>").addClass(instance.Option.StyleForPrefix);
        //item.Head.appendTo(item.Row);
        item.View = _view;
        item.View.dom().appendTo(item.Row);

        if (_data[instance.Option.PrimaryKey]) {
            //记录主键值
            item.PID = _data[instance.Option.PrimaryKey];
        }
        else {
            item.PID = "";
        }
        if (_data[instance.Option.ForginKey]) {
            //如果存在指定的外键值，尝试查找父元素对应的行
            for (var i = 0; i < vItems.length; i++) {
                if (vItems[i].PID == _data[instance.Option.ForginKey]) {
                    pItem = vItems[i];
                    item.TreeLv = pItem.TreeLv + 1;
                    item.Row.css('paddingLeft', item.TreeLv * 24);
                    item.PItem = pItem;
                    break;
                }
            }
        }
        item.Row.attr("TreeLv", item.TreeLv);
        item.Row.attr("RowIndex", item.RowIndex);
        //item.Head.attr("RowIndex", item.RowIndex);
        vItems.push(item);
        return item;
    };
    function findItemByKey(_key, _value) {
        var v;
        for (var i = 0; i < vItems.length; i++) {
            v = vItems[i];
            if (v.Data[_key] && v.Data[_key] === _value) {
                return v;
            }
        }
        return null;
    };
    function updateItem(_item) {
        _item.View = instance.af_makeView(_item.Data);

            //先获取所有更新目标的子级
            var sub = [];
            _item.Row.nextUntil("[TreeLv=" + _item.TreeLv + "]");

        //获取更新目标的新父项目
        var pItem;
        var deltaTreeLv
        for (var i = 0; i < vItems.length; i++) {
            if (vItems[i].PID == _item.Data[instance.Option.ForginKey]) {
                pItem = vItems[i];
                deltaTreeLv = _item.TreeLv - pItem.TreeLv - 1;
                _item.TreeLv = pItem.TreeLv + 1;
                _item.Row.css('paddingLeft', _item.TreeLv * 24);
                _item.Row.attr("TreeLv", _item.TreeLv);
                _item.PItem = pItem;
                break;
            }
        }

        //将要更新的目标与其所有子级的行元素合并
        var uRows = [_item.Row];

        //更新所有子级的缩进级别和位置
        for (var s = 0; s < sub.length; s++) {
            sub[s].TreeLv += deltaTreeLv;
            sub[s].Row.css('paddingLeft', sub[s].TreeLv * 24);
            sub[s].Row.attr("TreeLv", sub[s].TreeLv);
            uRows.push(sub[s].Row);
        }

        //将这些行元素移动到新的父元素之后
        if (pItem) {
            $(uRows[0]).insertAfter(pItem.Row);
        }
        else {
            instance._member.body.append(uRows);
        }
    };
    function updateRow(data) {
        this.Data = data;
        data[this.DataIndex] = data;
        this.View = instance.af_makeView(data);
        this.Row.html('').append(this.View.dom());
        return this;
    };

    function onRowDBClick(ev) {
        var i=$(this).attr('RowIndex');
        instance._fireEvent('itemDBClick', vItems[i]);
    };
    function onRowClick(ev) {
        var i = $(this).attr('RowIndex');
        if ($.isNumeric(i)&&i>-1&&i<vItems.length) {
            instance._fireEvent('itemClick', vItems[i]);
            slctItem(i);
        }
    };

    function slctItem(i) {
        if (instance.Option.Selectble == false) {
            return;
        }
        if (i < 0 || i >= vItems.length) {
            if (slctedItemIndex != -1) {
                vItems[slctedItemIndex].isSlcted = false;
                vItems[slctedItemIndex].Row.removeClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemUnslcted', vItems[slctedItemIndex]);
            }
            slctedItemIndex = -1;
            return;
        }
        if (focusedRow !== null) {
            focusedRow.removeClass(instance.Option.StyleForHot);
            focusedRow = null;
        }
        if (instance.Option.MultiSlctble) {
            //如果允许多选,直接切换所选项的选中状态
            if (vItems[i].isSlcted == true) {
                vItems[i].isSlcted = false;
                vItems[i].Row.removeClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemUnslcted', vItems[i]);
            }
            else {
                vItems[i].isSlcted = true;
                vItems[i].Row.addClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemSlcted', vItems[i]);
            }
        }
        else {
            //如果不允许多选，要判断当前选中项的状态
            if (slctedItemIndex == -1) {
                slctedItemIndex = i;
                vItems[i].isSlcted = true;
                vItems[i].Row.addClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemSlcted', vItems[i]);
            }
            else if (slctedItemIndex == i) {
                //slctedItemIndex = -1;
                //vItems[i].isSlcted = false;
                //vItems[i].Row.removeClass(instance.Option.StyleForSlcted);
                //instance._fireEvent('itemUnslcted', vItems[i]);
            }
            else {
                vItems[slctedItemIndex].isSlcted = false;
                vItems[slctedItemIndex].Row.removeClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemUnslcted', vItems[slctedItemIndex]);

                vItems[i].isSlcted = true;
                vItems[i].Row.addClass(instance.Option.StyleForSlcted);
                instance._fireEvent('itemSlcted', vItems[i]);
                slctedItemIndex = i;
            }
        }
    };
    function focusItem(i) {
        if (i < 0 || i >= vItems.length) {
            if (focusItemIndex != -1) {
                vItems[focusItemIndex].Row.removeClass(instance.Option.StyleForHot);
                instance._fireEvent('itemUnfocused', vItems[focusItemIndex]);
            }
            focusItemIndex = -1;
            return;
        }
        if (focusItemIndex == i) {
            instance._fireEvent('itemFocused', vItems[i]);
        }
        else {
            if (focusItemIndex > 0) {
                vItems[focusItemIndex].Row.removeClass(instance.Option.StyleForHot);
            }
            instance._fireEvent('itemUnfocused', vItems[focusItemIndex]);
            focusItemIndex = i;
            vItems[i].Row.addClass(instance.Option.StyleForHot);
            instance._fireEvent('itemFocused', vItems[i]);
        }
    };
    function doFilter() {
        if (fnGetKey == null) {
            return;
        }
        var nKey = fnGetKey();
        if (nKey == undefined || nKey == null) {
            return;
        }
        if (nKey === key) {
            jobFilter = setTimeout(doFilter, 300);
            return;
        }
        slctItem(-1);
        focusItem(-1);
        if (cache.length > 0 & nKey.indexOf(key) > -1) {
            key = nKey;
            //新的搜索key是原搜索key的扩展，直接从缓存结果中再过滤
            for (var i = 0; i < cache.length; i++) {
                var rowIndex = cache[i];
                if (fnPredicate(key, vItems[rowIndex].Data) == false) {
                    cache.splice(i, 1);
                    vItems[rowIndex].Row.hide();
                }
            }
        }
        else {
            key = nKey;
            cache = [];
            //否则从当前所有列表项中执行过滤
            for (var i = 0; i < vItems.length; i++) {
                if (fnPredicate(key, vItems[i].Data) == false) {
                    vItems[i].Row.hide();
                }
                else {
                    vItems[i].Row.show();
                    cache.push(i);
                }
            }
        }
        jobFilter = setTimeout(doFilter, 300);
    };
    function onKeyUp(ev) {
        if (instance.IsDisabled == true || instance.Visible == false || instance.IsDisposed == true) {
            return;
        }
        if (focusedRow !== null) {
            var nxt = focusedRow.prev('li').first();
            if (nxt.length > 0) {
                focusedRow.removeClass(instance.Option.StyleForHot);
                focusedRow = nxt.addClass(instance.Option.StyleForHot);
            }
        }
        else if (instance.Option.MultiSlctble == false && slctedItemIndex >= 0) {
            focusedRow = vItems[slctedItemIndex].Row.prev('li').first().addClass(instance.Option.StyleForHot);
        }
        else {
            focusedRow = vItems[vItems.length-1].Row.addClass(instance.Option.StyleForHot);
        }
        //focusItem(i);
    };
    function onKeyDown(ev) {
        if (instance.IsDisabled == true | instance.Visible == false | instance.IsDisposed == true) {
            return;
        }
        if (focusedRow !== null) {
            var nxt = focusedRow.next('li').first();
            if (nxt.length > 0) {
                focusedRow.removeClass(instance.Option.StyleForHot);
                focusedRow=nxt.addClass(instance.Option.StyleForHot);
            }
        }
        else if (instance.Option.MultiSlctble == false && slctedItemIndex >= 0) {
            focusedRow = vItems[slctedItemIndex].Row.next('li').first().addClass(instance.Option.StyleForHot);
        }
        else {
            focusedRow = vItems[0].Row.addClass(instance.Option.StyleForHot);
        }
        //focusItem(i);
    };
    function onKeyEnter(ev) {
        if (instance.IsDisabled == true || instance.Visible == false || instance.IsDisposed == true) {
            return;
        }
        if (focusedRow !== null) {
            var i = focusedRow.attr('RowIndex');
            if (i && i >= 0) {
                slctItem(i);
            }
        }
    };

    this.Append = function (_data,_pos) {
        /// <summary>
        /// 向列表尾部追加数据
        /// </summary>
        /// <param name="_datas"></param>
        /// <returns type=""></returns>
        if (ObjHelper.IsEmpty(_data)) {
            return this;
        }
        if (!Array.isArray(_data)) {
            _data = new Array(_data);
        }
        if (ObjHelper.IsEmpty(_pos) || !$.isNumeric(_pos)) {
            _pos = -1;
        }
        //appendData(_data,_pos,_isSub?true:false);
        append(_data, _pos);
        return this;
    };

    this.Prepend = function (_data,_pos) {
        /// <summary>
        /// 向列表前部插入数据
        /// </summary>
        /// <param name="_datas"></param>
        /// <returns type=""></returns>
        if (ObjHelper.IsEmpty(_data)) {
            return this;
        }
        if (!Array.isArray(_data)) {
            _data = new Array(_data);
        }
        if (ObjHelper.IsEmpty(_pos) || !$.isNumeric(_pos)) {
            _pos = -1;
        }
        prepend(_data,_pos);
        return this;
    };

    this.Update = function (_objKey,_newObj) {
        /// <summary>
        /// 根据没个列表项的数据对象的指定属性值找到并更新目标数据以及所有子项
        /// </summary>
        /// <param name="_objKey"></param>
        /// <param name="_newObj"></param>
        if (ObjHelper.IsEmpty(_newObj[_objKey])) {
            console.log('更新列表项时提供的数据对象未包含特定查找键');
            return this;
        }
        var i = findItemByKey(_objKey, _newObj[_objKey]);
        i.Data = _newObj;
        data[i.DataIndex] = _newObj;

        updateItem(i);
    };

    this.Clear = function () {
        data = [];
        for (var i = 0, n = vItems.length; i < n; i++) {
            vItems[i].View.dispose();
            vItems[i].Row.remove();
        }
        vItems = [];
        if (instance.Option.ShowNullTip == true) {
            instance._member.body.append(nullTip.show());
        }
        else {
            nullTip.hide().appendTo(tmp);
        }
        return this;
    };

    this.Filter = function (_fnGetKey, _fnPredicate) {
        /// <summary>
        /// 设置或启动列表项自动过滤
        /// </summary>
        /// <param name="_fnGetKey"></param>
        /// <param name="_fnPredicate"></param>
        /// <returns type=""></returns>
        if (ObjHelper.IsFunc(_fnGetKey) && ObjHelper.IsFunc(_fnPredicate)) {
            fnGetKey = _fnGetKey;
            fnPredicate = _fnPredicate;
        }
        else {
            jobFilter = setTimeout(doFilter, 10);
        }

        return this;
    };

    this.StopFilter = function () {
        if (jobFilter !== null) {
            clearTimeout(jobFilter);
            jobFilter = null;
        }
        return this;
    };

    this.Unfilter = function () {
        /// <summary>
        /// 取消过滤结果
        /// </summary>
        if (jobFilter !== null) {
            clearTimeout(jobFilter);
            jobFilter = null;
        }
        cache = [];
        for (var i = 0; i < vItems.length; i++) {
            vItems.Row.show();
        }
        return this;
    };

    this.Find = function (_fnPredicate) {
        /// <summary>
        /// 从当前可见列表项中找到符合条件的项
        /// </summary>
        /// <param name="_fnPredicate"></param>
        if (ObjHelper.IsFunc(_fnPredicate)) {
            for (var i = 0; i < vItems.length; i++) {
                if (_fnPredicate.call(this, vItems[i]) === true) {
                    return vItems[i];
                }
            }
        }
        return null;
    };

    this.Select = function (_index) {
        /// <summary>
        /// 选中指定索引的行或者获取已经选中的行
        /// </summary>
        /// <param name="_index"></param>
        /// <returns type=""></returns>
        if (ObjHelper.IsEmpty(_index)) {
            if (instance.Option.MultiSlctble == true) {
                var slcted = [];
                for (var i = 0; i < vItems.length; i++) {
                    if (vItems[i].isSlcted == true) {
                        slcted.push(vItems[i]);
                    }
                }
                return slcted;
            }
            else if (slctedItemIndex > -1) {
                return vItems[slctedItemIndex];
            }
        }
        else if ($.isNumeric(_index)) {
            slctItem(_index);
            return instance.Select();
        }
        else {
            return this;
        }
    };

    this.Data = function () {
        return data;
    };

    this.Scroller = function (_display) {
        if (_display == true&&!instance._member.scl) {
            instance._member.scl = new Scroller(instance._member.body);
        }
        else if (_display == false&&instance._member.scl) {
            instance._member.scl.dispose();
            instance._member.scl = null;
        }
        else {
            instance._member.scl.Reset();
        }
        return this;
    };

    this.af_makeView = function (_data) {
        /// <summary>
        /// 由列表使用者负责创建UI视图并绑定数据
        /// </summary>
        /// <param name="_data"></param>
        /// <returns type=""></returns>
        return $('<div>').html(_data);
    };

    instance._member.vf_onClick = function () {
        //由于全局键盘事件只对最后注册的控件有效，所以在列表被点击时需重新绑定，以防界面上其他列表控件干扰
        KeybordHelper.globalOn('up', onKeyUp);
        KeybordHelper.globalOn('down', onKeyDown);
        KeybordHelper.globalOn('enter', onKeyEnter);
    };
    instance._member.vf_onShow = function () {
        slctItem(-1);
        focusItem(-1);
        KeybordHelper.globalOn('up', onKeyUp);
        KeybordHelper.globalOn('down', onKeyDown);
        KeybordHelper.globalOn('enter', onKeyEnter);
    };
    instance._member.vf_onHide = function () {
        if (jobFilter) {
            clearTimeout(jobFilter);
            jobFilter = null;
        }
        KeybordHelper.globalOff('up', onKeyUp);
        KeybordHelper.globalOff('down', onKeyDown);
        KeybordHelper.globalOff('enter', onKeyEnter);
        cache = [];
    };
    instance._member.vf_onDispose = function () {
        KeybordHelper.globalOff('up', onKeyUp);
        KeybordHelper.globalOff('down', onKeyDown);
        KeybordHelper.globalOff('enter', onKeyEnter);
    };

    List.constructor = List;
    return this;
}
List.prototype = Controller.prototype;
ListOption = {
    StyleForHead: 'ListHead',
    StyleForBody: 'ListBody',
    StyleForFoot: 'ListFoot',
    StyleForRow: 'ListRow',
    StyleForPrefix:'',
    StyleForSlcted: 'slcted',
    StyleForHot: 'hotItem',
    StyleForNull:'NoItem',
    ShowHead: true,
    ShowFoot: true,
    VirtualMode:false, //虚拟模式，适于加载大量数据
    Selectble: false, //是否可被选中
    MultiSlctble:false, //是否允许多选
    PrimaryKey: 'IDStr',
    ForginKey: 'PIdStr',
    ShowNullTip:true,
    TipForNull:'没有符合条件的记录',
    Propagation: true
}
//#endregion

//#region 布局控件-对话框
function DialogBox(_srcElm,_opt) {
    Controller.call(this, _srcElm, _opt);
    var instance = this;
    window.tmpDialogHost = document.createDocumentFragment();
    window.tmpDialogHost.appendChild(instance._member.$rootElm[0]);
    instance.ElmOnDefault = null;
    instance.Option = $.extend({}, this.Option, DialogBoxOption,_opt);
    instance._member.$rootElm.addClass(instance.Option.StyleForWnd);
    instance._member.Header = $("<div>").addClass(instance.Option.StyleForHeader).prependTo(instance._member.$rootElm);
    instance._member.btnClost = $("<div>").addClass(instance.Option.StyleForCloser).appendTo(instance._member.Header).on("click",closeWnd);

    function onKeyESC() {
        instance.hide();
    };
    function onKeyCtrlEnter() {
        if (ObjHelper.IsEmpty(instance.ElmOnDefault)) {
            return;
        }
        else {
            instance.ElmOnDefault.click();
        }
    };

    function closeWnd() {
        instance.hide();
    };

    this.DefaultAction = function (_actionElm) {
        /// <summary>
        /// 设置当用户按下ctrl+enter时默认触发click事件的目标元素
        /// </summary>
        /// <param name="_actionElm"></param>
        /// <returns type=""></returns>
        if (ObjHelper.IsEmpty(_actionElm)) {
            instance.ElmOnDefault = null;
            return this;
        }
        instance.ElmOnDefault = _actionElm;
        if (_actionElm instanceof Controller) {
            instance._member.$rootElm.append(_actionElm.dom());
        }
        else {
            instance._member.$rootElm.append(_actionElm);
        }
        return this;
    };

    instance._member.vf_onShow = function () {
        $("body").Mask(instance._member.$rootElm.hide());
        instance._member.$rootElm.fadeIn();
        KeybordHelper.globalOn("esc", onKeyESC);
        KeybordHelper.globalOn("ctrl+enter", onKeyCtrlEnter);
        LayoutHelper.Layout2Parent(instance._member.$rootElm, "AllCenter");
    };

    instance._member.vf_onHide = function () {
        window.tmpDialogHost.appendChild(instance._member.$rootElm[0]);
        KeybordHelper.globalOff("esc", onKeyESC);
        KeybordHelper.globalOff("ctrl+enter", onKeyCtrlEnter);
        $('body').Unmask();
    };

    KeybordHelper.globalOn("esc", onKeyESC);
    KeybordHelper.globalOn("ctrl+enter", onKeyCtrlEnter);
    DialogBox.constructor = DialogBox;
    return this;
}
DialogBox.prototype = Controller.prototype;
var DialogBoxOption = {
    StyleForWnd: "DialogBox",
    StyleForHeader: "DBHeader",
    StyleForCloser: "DBCloser",
    Propagation: true
}
//#endregion

//#region 组合控件-下拉单选
function Dropdown(_srcElm, _opt) {
    Controller.call(this, _srcElm, _opt);
    var instance = this;
    this.Option = $.extend({}, this.Option, DropdownOption, _opt);

    this.constructor = Dropdown;
    return instance;
};
Dropdown.prototype = Controller.prototype;
DropdownOption = {

}
//#endregion

//#region 组合控件-可联动多层选择
function TreeSelector(_srcElm, _opt) {
    Controller.call(this, _srcElm, _opt);
    var instance = this;
    this.Option = $.extend({}, this.Option, TreeSelectorOption, _opt);

    this.constructor = TreeSelector;
    return instance;
};
TreeSelector.prototype = Controller.prototype;
TreeSelectorOption = {

}
//#endregion

//#region 布局控件-模态对话窗体
function Dialoger(flateMode) {
    /// <summary>
    /// 创建一个对话框窗体
    /// </summary>
    /// <param name="flateMode">是否使用扁平模式[与背景融合]</param>
    /// <returns type=""></returns>
    Controller.call(this);
    var instance = this;
    var closeDelay = null;
    var autoCloser = null;
    var isDisposed = false;
    var btnEnter = null;
    var btnEsc = null;
    var btnAbandon = null;
    var FlateMode = flateMode;
    if (!FlateMode) {
        instance._member.$rootElm.addClass('DialogBox');
    }
    instance._member.$rootElm.css('minWidth', '400px').css('minHeight', '250px');
    var body = $("<div style='width:auto'>");
    var foot = $("<div>").addClass('DialogFoot');
    instance._member.$rootElm.append(body).append(foot);
    instance._member.$rootElm.append($("<div style='clear:both'>"));

    function onKeyEsc(ev) {
        if (btnEsc) {
            btnEsc.click();
            instance.hide();
        }
        else {
            instance.hide();
        }
    };

    function onKeyEnter(ev) {
        if (btnEnter) {
            btnEnter.click();
        }
    };

    function defEsc() {
        instance.hide();
    };

    instance._member.vf_onShow = function () {
        $('body').Mask(instance._member.$rootElm);
        instance._member.$rootElm.show().addClass('fadeIn');
        LayoutHelper.Layout2Parent(instance._member.$rootElm, "AllCenter");
        KeybordHelper.globalOn('esc', onKeyEsc);
        KeybordHelper.globalOn('ctrl+enter', onKeyEnter);
    };

    instance._member.vf_onHide = function () {
        $('body').Unmask();
        instance._member.$rootElm.hide().removeClass('fadeIn');
        KeybordHelper.globalOff('esc', onKeyEsc);
        KeybordHelper.globalOff('ctrl+enter', onKeyEnter);
    };

    instance._member.vf_disable = function (msg) {
        instance._member.$rootElm.Mask(msg);
    };

    instance._member.vf_enable = function () {
        instance._member.$rootElm.Unmask();
    };

    this.Content = function (cnt) {
        if (ObjHelper.IsEmpty(cnt)) {
            return instance._member.$rootElm.children();
        }
        else if (ObjHelper.IsElement(cnt)) {
            body.html('').append(cnt);
            if (FlateMode == true) {
                instance._member.$rootElm.width(cnt.width());
            }
            LayoutHelper.Layout2Parent(cnt, 'AllCenter');
            return instance;
        }
        else {
            body.html('').text(cnt.toString());
            return instance;
        }
    };

    this.BtnEnter = function (_title, _fn,_btnStyle) {
        if (_title) {
            btnEnter = new Button().Title(_title.toString()).addClass(_btnStyle);
            if (ObjHelper.IsFunc(_fn)) {
                btnEnter.on('click', _fn);
            }
            foot.append(btnEnter.dom());
        }
        else if (btnEnter) {
            btnEnter.dom().remove();
            btnEnter.dispose();
            btnEnter = null;
        }
        else {

        }
        return this;
    };

    this.BtnEsc = function (_title, _fn, _btnStyle) {
        if (_title) {
            btnEsc = new Button().Title(_title.toString()).addClass(_btnStyle);
            btnEsc.on('click', defEsc);
            if (ObjHelper.IsFunc(_fn)) {
                btnEsc.on('click', _fn);
            }
            foot.append(btnEsc.dom());
        }
        else if (btnEsc) {
            btnEsc.dom().remove();
            btnEsc.dispose();
            btnEsc = null;
        }
        else {

        }
        return this;
    };

    this.BtnAbandon = function (_title, _fn, _btnStyle) {
        if (_title) {
            btnAbandon = new Button().Title(_title.toString()).addClass(_btnStyle);
            if (ObjHelper.IsFunc(_fn)) {
                btnAbandon.on('click', _fn);
            }
            foot.append(btnAbandon.dom());
        }
        else if (btnAbandon) {
            btnAbandon.dom().remove();
            btnAbandon.dispose();
            btnAbandon = null;
        }
        else {

        }
        return this;
    };

    this.constructor = Dialoger;
    return this;
}
Dialoger.prototype = Controller.prototype;
//#endregion

